package app;

import java.util.HashSet;
import java.util.Set;

import org.mt4j.MTApplication;
import org.mt4j.sceneManagement.Iscene;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import command.Command;
import command.RemoteCommandRunner;

import model.ApplicationModel;
import model.Project;

import view.interfaces.ApplicationView;
import view.interfaces.screen.View;
import view.interfaces.screen.menu.AppHomeView;
import view.interfaces.screen.menu.JoinProjectMenuView;
import view.interfaces.screen.menu.ManageProjectsMenuView;
import view.interfaces.screen.menu.NewProjectMenuView;
import view.interfaces.screen.project.ProjectView;
import view.mt4j.scene.menu.AppHomeScene;
import view.mt4j.scene.menu.JoinProjectMenuScene;
import view.mt4j.scene.menu.ManageProjectsMenuScene;
import view.mt4j.scene.menu.NewProjectMenuScene;
import view.mt4j.scene.project.ProjectScene;

import controller.ApplicationController;

public class MTStatechartLauncher extends MTApplication implements
		ApplicationView {

	private static final long serialVersionUID = -682680964281905831L;
	private static final Logger log = LoggerFactory
			.getLogger(MTStatechartLauncher.class);

	public static void main(String[] args) {
		try {
			initialize();
		} catch (Exception ex) {
			System.out.println("ERROR");
			System.exit(1);
		}
	}

	private ApplicationModel model;
	private ApplicationController controller;
	private ApplicationController applicationController;

	private AppHomeScene appHomeScene;
	private NewProjectMenuScene newProjectMenuScene;
	private ManageProjectsMenuScene manageProjectsMenuScene;
	private JoinProjectMenuScene joinProjectMenuScene;
	private ProjectScene projectScene;

	public MTStatechartLauncher() {
		log.info("Application initialization...");
		model = initModel();
		controller = ApplicationController.create(model, this);

		log.info("Application ready, setting controller");
		setApplicationController(controller);
	}

	private ApplicationModel initModel() {
		log.debug("initializing model ...");
		Set<Project> projects = new HashSet<Project>();
		Set<Project> autoLoadedProjects = autoLoadProjects();
		if (autoLoadedProjects != null) {
			log.debug("initializing model : adding auto loaded projects");
			projects.addAll(autoLoadedProjects);
		} else {
			log.debug("initializing model : no projects to load");
		}
		ApplicationModel model = new ApplicationModel(projects);
		log.debug("initializing model DONE");
		return model;
	}

	private Set<Project> autoLoadProjects() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void startUp() {
		log.info("startUp");
		initScenes();
		// controller.showAppHomeView();
	}

	private void initScenes() {
		log.debug("initScenes ...");
		// first view will be opened when application starts
//		 addScene(new AbstractScene(this, "splash") {
//		 });

		appHomeScene = new AppHomeScene(this, model);
		newProjectMenuScene = new NewProjectMenuScene(this, model);
		joinProjectMenuScene = new JoinProjectMenuScene(this, model);
		manageProjectsMenuScene = new ManageProjectsMenuScene(this, model);
		projectScene = new ProjectScene(this, model);
		
		
		addScene(appHomeScene);
		log.debug("initScenes DONE");
	}

	public void setApplicationController(
			final ApplicationController applicationController) {
		invokeLater(new Runnable() {

			@Override
			public void run() {
				log.debug("setApplicationController ...");
				appHomeScene.setController(applicationController);
				newProjectMenuScene.setController(applicationController);
				joinProjectMenuScene.setController(applicationController);
				manageProjectsMenuScene.setController(applicationController);
				projectScene.setController(applicationController);
				log.debug("setApplicationController DONE");
			}
		});

	}

	@Override
	public NewProjectMenuView getNewProjectMenuView() {
		return newProjectMenuScene;
	}

	@Override
	public ManageProjectsMenuView getManageProjectsMenuView() {
		return manageProjectsMenuScene;
	}

	@Override
	public JoinProjectMenuView getJoinProjectMenuView() {
		return joinProjectMenuScene;
	}

	@Override
	public ProjectView getProjectView() {
		return projectScene;
	}

	@Override
	public AppHomeView getAppHomeView() {
		return appHomeScene;
	}

	@Override
	public void showView(final View view) {
		invokeLater(new Runnable() {

			@Override
			public void run() {
				log.debug("showView {}", view.getClass().getSimpleName());
				pushScene();
				changeScene((Iscene) view);
			}
		});

	}

	@Override
	public void runRemoteCommand(Command command) {
		invokeLater(new RemoteCommandRunner(applicationController, command));
	}

}
